package com.ruoyi.flow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.flow.domain.TWorkflow;
import com.ruoyi.flow.domain.bo.TWorkflowBo;
import com.ruoyi.flow.domain.vo.TWorkflowVo;
import com.ruoyi.flow.mapper.TWorkflowMapper;
import com.ruoyi.flow.service.ITWorkflowService;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.RoleDTO;
import lombok.RequiredArgsConstructor;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Instance;
import org.dromara.warm.flow.core.service.InsService;
import org.dromara.warm.flow.core.service.TaskService;
import org.dromara.warm.flow.core.utils.IdUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工作流Service业务层处理
 *
 * @author zzneko
 * @date 2025-07-14
 */
@RequiredArgsConstructor
@Service
public class TWorkflowServiceImpl implements ITWorkflowService {

    private final TWorkflowMapper baseMapper;
    private final InsService insService;
    private final TaskService taskService;


    /**
     * 查询工作流
     */
    @Override
    public TWorkflowVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询工作流列表
     */
    @Override
    public TableDataInfo<TWorkflowVo> queryPageList(TWorkflowBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TWorkflow> lqw = buildQueryWrapper(bo);
        Page<TWorkflowVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询工作流列表
     */
    @Override
    public List<TWorkflowVo> queryList(TWorkflowBo bo) {
        LambdaQueryWrapper<TWorkflow> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TWorkflow> buildQueryWrapper(TWorkflowBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TWorkflow> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getType() != null, TWorkflow::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getReason()), TWorkflow::getReason, bo.getReason());
        lqw.eq(bo.getServiceId() != null, TWorkflow::getServiceId, bo.getServiceId());
        lqw.eq(bo.getFlowStatus() != null, TWorkflow::getFlowStatus, bo.getFlowStatus());
        lqw.like(bo.getCreateBy() != null, TWorkflow::getCreateBy, bo.getCreateBy());
        return lqw;
    }

    /**
     * 新增工作流
     */
    @Override
    public Boolean insertByBo(TWorkflowBo bo) {
        TWorkflow add = BeanUtil.toBean(bo, TWorkflow.class);
        String id = IdUtils.nextIdStr();
        add.setId(id);
        //设定流程
        FlowParams flowParams = FlowParams.build().flowCode(bo.getType());
        String userId = LoginHelper.getUserId().toString();
        flowParams.handler(userId);
        Map<String, Object> variable = new HashMap<>();
        variable.put("businessType",bo.getType());
        variable.put("businessData",bo);
        flowParams.variable(variable);
        Instance instance = insService.start(id, flowParams);
        add.setInstanceId(instance.getId());
        add.setNodeCode(instance.getNodeCode());
        add.setNodeName(instance.getNodeName());
        add.setNodeName(instance.getNodeName());
        add.setFlowStatus(instance.getFlowStatus());
        add.setCreateTime(DateUtils.getNowDate());
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改工作流
     */
    @Override
    public Boolean updateByBo(TWorkflowBo bo) {
        TWorkflow update = BeanUtil.toBean(bo, TWorkflow.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TWorkflow entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除工作流
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean handle(TWorkflowBo tWorkflowBo, Long taskId, String skipType, String message, String nodeCode, String flowStatus) {
        LoginUser user = LoginHelper.getLoginUser();
        // 是通过流程还是退回流程 【必传】
        FlowParams flowParams = FlowParams.build().skipType(skipType);
        // 作为办理人保存到历史记录表 【必传】
        flowParams.handler(user.getUserId().toString());
        // 如果需要任意跳转流程，传入此参数  【按需传】
        flowParams.nodeCode(nodeCode);
        // 作为审批意见保存到历史记录表  【按需传】
        flowParams.message(message);

        // 设置办理人拥有的权限，办理中需要校验是否有权限办理 【必传】
        List<String> permissionList = new ArrayList<>();
        user.getRoles().stream().forEach(x->{
            permissionList.add("role:"+x.getRoleId());
        });
        permissionList.add("dept:" + user.getDeptId());
        permissionList.add(user.getUserId().toString());
        flowParams.permissionFlag(permissionList);

        // 流程变量
        Map<String, Object> variable = new HashMap<>();
        // 流程变量传递业务数据，按实际业务需求传递  【按需传】
        variable.put("businessType", tWorkflowBo.getType());
        flowParams.variable(variable);
        Instance instance = taskService.skip(taskId, flowParams);
        return instance != null;
    }
}
